package com.cashbook.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.http.HttpException;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;

/**
 * controller
 * 
 * @author Administrator
 *
 */
@RestController
@RequestMapping("/file")
public class FileUploadController {

	// log日志
	// private static Logger logger = Logger.getLogger(AliyunOSSClientUtil.class);
	// 阿里云API的内或外网域名
	private static String ENDPOINT;
	// 阿里云API的密钥Access Key ID
	private static String ACCESS_KEY_ID;
	// 阿里云API的密钥Access Key Secret
	private static String ACCESS_KEY_SECRET;
	// 阿里云API的bucket名称
	private static String BACKET_NAME;
	// 阿里云API的文件夹名称
	private static String FOLDER;
	// 初始化 oss 客户端
	private static OSSClient ossClient = null;
	// 初始化属性
	static {
		ENDPOINT = "http://oss-cn-shenzhen.aliyuncs.com";
		ACCESS_KEY_ID = "LTAIK7hejUMHlih8";
		ACCESS_KEY_SECRET = "3Y7EXFJYI4trzBLngb2RbxrPOCYlHY";
		BACKET_NAME = "guanaibang";
		FOLDER = "cashbook/images/";

		ossClient = new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
	}

	/**
	 * 返回全部列表
	 * 
	 * @return
	 * @throws IOException
	 * @throws IllegalStateException
	 */
	@RequestMapping("/upload")
	public Map upload(MultipartFile file, HttpServletRequest request, Model model)
			throws IllegalStateException, IOException {
		Map<String, Object> result = null;
		if (file != null) {
			if (!file.isEmpty()) {
				/* springMVC 多部件文件对象转 File 对象 */
				CommonsMultipartFile cf = (CommonsMultipartFile) file;
				DiskFileItem fi = (DiskFileItem) cf.getFileItem();
				/* File f = fi.getStoreLocation(); */
				File f = null;
				try {
					/*
					 * 导致文件转换中错误，文件不可读从而导致 程序抛出 is not a normal file 异常。
					 * 因为错误出现的随机性很大，所以选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 。
					 */
					f = File.createTempFile("tmp", null);
					file.transferTo(f);
					f.deleteOnExit();
				} catch (IOException e) {
					e.printStackTrace();
				}
				result = uploadObject2OSS(ossClient, f, BACKET_NAME, FOLDER);
				//System.out.println(result);
			}
		}
		return result;
	}

	/**
	 * 上传图片至OSS
	 * 
	 * @param ossClient
	 *            oss连接
	 * @param file
	 *            上传文件（文件全路径如：D:\\image\\cake.jpg）
	 * @param bucketName
	 *            存储空间
	 * @param folder
	 *            模拟文件夹名 如"qj_nanjing/"
	 * @return String 返回的唯一MD5数字签名
	 */
	public static Map<String, Object> uploadObject2OSS(OSSClient ossClient, File file, String bucketName,
			String folder) {
		// 存储返回值信息
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, Object> map2 = new HashMap<String, Object>();

		try {
			// 以输入流的形式上传文件
			InputStream is = new FileInputStream(file);

			// 获得文件类型（可以判断如果不是图片，禁止上传）
			String contentType = getContentType(file.getName());
			// 获得文件后缀名
			String suffixName = "." + contentType.substring(contentType.indexOf("/") + 1);
			// 调整后的文件名
			String fileName = UUID.randomUUID().toString().replaceAll("-", "") + suffixName;
			//System.out.println(fileName);
			// 文件大小
			Long fileSize = file.length();
			// 创建上传Object的Metadata
			ObjectMetadata metadata = new ObjectMetadata();
			// 上传的文件的长度
			metadata.setContentLength(is.available());
			// 指定该Object被下载时的网页的缓存行为
			metadata.setCacheControl("no-cache");
			// 指定该Object下设置Header
			metadata.setHeader("Pragma", "no-cache");
			// 指定该Object被下载时的内容编码格式
			metadata.setContentEncoding("utf-8");
			// 文件的MIME，定义文件的类型及网页编码，决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成，
			// 如果没有扩展名则填默认值application/octet-stream
			metadata.setContentType(getContentType(fileName));
			// 指定该Object被下载时的名称（指示MINME用户代理如何显示附加的文件，打开或下载，及文件名称）
			metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
			// 上传文件 (上传文件流的形式)
			PutObjectResult putResult = ossClient.putObject(bucketName, folder + fileName, is, metadata);
			OSSObject object = ossClient.getObject(BACKET_NAME, FOLDER + fileName);
			// 图片在 oss 对象存储空间中的 路径
			String ossPath = "https://guanaibang.oss-cn-shenzhen.aliyuncs.com/" + object.getKey();

			/* 上传成功 */
			map.put("code", 0);// 0表示成功，1失败
			map.put("msg", "上传成功");// 提示消息
			map.put("data", map2);

			map2.put("src", ossPath);// 图片url,页面调用数据书写格式 data.src
		} catch (Exception e) {
			e.printStackTrace();

			/* 上传失败 */
			map.put("code", 1);// 0表示成功，1失败
			map.put("msg", "上传失败");// 提示消息
		}
		return map;
	}

	/**
	 * 通过文件名判断并获取OSS服务文件上传时文件的contentType
	 * 
	 * @param fileName
	 *            文件名
	 * @return 文件的contentType
	 */
	public static String getContentType(String fileName) {
		// 文件的后缀名
		String fileExtension = fileName.substring(fileName.lastIndexOf("."));
		if (".bmp".equalsIgnoreCase(fileExtension)) {
			return "image/bmp";
		}
		if (".gif".equalsIgnoreCase(fileExtension)) {
			return "image/gif";
		}
		if (".jpeg".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension)
				|| ".png".equalsIgnoreCase(fileExtension)) {
			return "image/jpeg";
		}
		if (".html".equalsIgnoreCase(fileExtension)) {
			return "text/html";
		}
		if (".txt".equalsIgnoreCase(fileExtension)) {
			return "text/plain";
		}
		if (".vsd".equalsIgnoreCase(fileExtension)) {
			return "application/vnd.visio";
		}
		if (".ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) {
			return "application/vnd.ms-powerpoint";
		}
		if (".doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) {
			return "application/msword";
		}
		if (".xml".equalsIgnoreCase(fileExtension)) {
			return "text/xml";
		}
		// 默认返回类型
		return "image/jpeg";
	}

}
